from pyecharts.charts import Kline,Bar,Line,Grid,EffectScatter,Timeline
import pyecharts.options as opts
from pyecharts.globals import SymbolType
import pandas as pd
from jili.trade.constants import bs
import os
from jili.tool.convert import str2datetime
import talib
MA=talib.SMA
js_host="F:/pyecharts-assets/assets/"
"""
场景：
1.K线图
2.分时图
3.辅助指标
4.净值图
5.
"""
class chart:
    def __init__(self,data=None,timekey_strn=19,start=None,end=None,name="",is_sub_show=True):
        """

        Args:
            data: bar数据，或是分时图数据
            timekey_strn: timekey保留位数
            使用上
        """
        self.start=start
        self.end=end
        self.is_sub_show=is_sub_show
        self.grad_index=1
        self.isextend_axis=True
        self.mainchart=None
        self.data=None
        self.x=None
        self.sub_charts=[]
        self.timekey_strn=timekey_strn
        self.x,self.data=self.getbars(data)
        self.isreturn=False
        self.name=name
        self.orders_n=1
    def getbars(self,data):
        x=None
        d=None
        if isinstance(data,list):
            d=pd.DataFrame(data)
            d.index = d["timekey"]
            d.sort_index(inplace=True)
            d.drop_duplicates("timekey", inplace=True)
        elif isinstance(data,dict):
            d = pd.DataFrame(data).T
            d.index=d["timekey"]
            d.sort_index(inplace=True)
            d.drop_duplicates("timekey", inplace=True)
        else:
            d=data
        if isinstance(d,pd.DataFrame):
            if "timekey" in d.columns:
                x= d["timekey"].apply(lambda x: str(x)[:self.timekey_strn]).tolist()
        return x,d
    def get_x_y(self,x,y):
        if self.start:
            start = str(self.start)[:self.timekey_strn]
            if self.end:
                end = str(self.end)[:self.timekey_strn]
                n1 = 0
                n2=0
                for i in x:
                    if i < start:
                        n1 = n1 + 1
                    if i>end:
                        break
                    n2=n2+1
                return x[n1:n2], y[n1:n2]
            else:
                n1 = 0
                for i in x:
                    if i >= start:
                        break
                    n1 = n1 + 1
                return x[:n1], y[:n1]
        else:
            if self.end:
                end = str(self.end)[:self.timekey_strn]
                n1=0
                for i in x:
                    if i>end:
                        break
                    n1=n1+1
                return x[:n1],y[:n1]
            else:
                return x,y
    def prepare_data(self,data=None,field=None):
        x = []
        y = []
        if isinstance(data, dict):
            if field:
                for k,v in data.items():
                    x.append(str(k)[:10])
                    y.append(v[field])
            else:
                for i in data.keys():
                    x.append(str(i)[:10])
                y = list(data.values())
        elif isinstance(data, pd.DataFrame):
            if field:
                for i in list(data.index):
                    x.append(str(i)[:10])
                y = data[field].tolist()
        elif isinstance(data, pd.Series):
            for i in list(data.index):
                x.append(str(i)[:10])
            y = data.tolist()
        elif isinstance(data, list):
            if len(data) == 2:
                if isinstance(data[0],list):
                    x = data[0]
                    y = data[1]
            else:
                if field:
                    for i in data:
                        x.append(str(i["timekey"])[:10])
                        y.append(i[field])
                else:
                    y=data
        else:
            x=self.x
            y=self.data[field].to_list()
        return x,y
    def mainchart_net(self,data,name="净值",field="net"):
        # self.isreturn=True
        x, y = self.prepare_data(data, field=field)

        self.mainchart = Line()
        self.mainchart.add_xaxis(self.x)
        self.mainchart.add_yaxis(name, y, is_smooth=True, is_symbol_show=False,
                                 tooltip_opts=opts.TooltipOpts(trigger="axis"), )
        self.mainchart.set_global_opts(yaxis_opts=opts.AxisOpts(
            min_="dataMin",
            max_="dataMax",
            # axislabel_opts=opts.LabelOpts(is_show=True),
            # axisline_opts=opts.AxisLineOpts(is_show=True),
            # axistick_opts=opts.AxisTickOpts(is_show=True),
            splitline_opts=opts.SplitLineOpts(is_show=True), ))
        if not self.x:
            self.x = x
    def add_net(self,data,name="净值",field="net"):
        x,y=self.prepare_data(data,field=field)
        if x:
            self.mainchart.add_yaxis(
                series_name=name,
                y_axis=y,
                yaxis_index=0,
                is_smooth=True, is_symbol_show=False,
            )
    # def add_topindex(self,data,name="回撤",field="net"):
    #     if self.isextend_axis:
    #         self.mainchart.extend_axis(
    #             yaxis=opts.AxisOpts(
    #                 name="指标",
    #                 max_=3,
    #                 is_inverse=True,
    #                 axistick_opts=opts.AxisTickOpts(is_show=False),
    #                 splitline_opts=opts.SplitLineOpts(is_show=True),
    #             ))
    #         self.isextend_axis=False
    #     x,y=self.prepare_data(data,field)
    #     self.mainchart.add_yaxis(
    #         series_name=name,
    #         y_axis=y,
    #         yaxis_index=1,
    #         is_selected=True,
    #         linestyle_opts=opts.LineStyleOpts(),
    #         areastyle_opts=opts.AreaStyleOpts(opacity=0.1),
    #         label_opts=opts.LabelOpts(is_show=False),
    #     )

    def mainchart_fenshitu(self,a=["close","volume"]):
        self.mainchart = Line()
        self.mainchart.add_xaxis(self.x)
        self.mainchart.add_yaxis("分时", self.data[a[0]].values.tolist(), is_smooth=True, is_symbol_show=False,
                           tooltip_opts=opts.TooltipOpts(trigger="axis"),)
        self.mainchart.set_global_opts(yaxis_opts=opts.AxisOpts(
                min_="dataMin",
                max_="dataMax",
                # axislabel_opts=opts.LabelOpts(is_show=True),
                # axisline_opts=opts.AxisLineOpts(is_show=True),
                # axistick_opts=opts.AxisTickOpts(is_show=True),
                splitline_opts=opts.SplitLineOpts(is_show=True),))
        if len(a)==2:
            self._vol_chart(vol=a[1])
    def set_mainchart(self,c,isreturn=True):
        self.mainchart=c
        self.isreturn = isreturn
    def mainchart_kline(self,a=["timekey","open","close","low","high","volume"]):
        self.mainchart = Kline()
        if a:
            if len(a)==5:
                if isinstance(a[0],str):
                    x = self.data[a[0]].apply(lambda x: str(x)[:self.timekey_strn]).tolist()
                    self.x=x
                    self.mainchart.add_xaxis(x)
                    self.mainchart.add_yaxis("kline",
                    self.data.loc[:, [a[1], a[2], a[3], a[4]]].values.tolist(),
                    itemstyle_opts = opts.ItemStyleOpts(
                        color="#ec0000",
                        color0="#00da3c",
                        border_color="#8A0000",
                        border_color0="#008F28",
                    ))
                    # self._vol_chart()
                else:
                    self.x=a[0]
                    self.mainchart.add_xaxis(a[0])
                    self.mainchart.add_yaxis("kline",[a[1],a[2],a[3],a[4]],
                                         itemstyle_opts=opts.ItemStyleOpts(
                                             color="#ec0000",
                                             color0="#00da3c",
                                             border_color="#8A0000",
                                             border_color0="#008F28",
                                         ))
                    #self._vol_chart()
            elif len(a)==4:
                self.mainchart.add_xaxis(self.x)
                if isinstance(a[0],str):
                    self.mainchart.add_yaxis("kline",
                                         self.data.loc[:, [a[0], a[1], a[2], a[3]]].values.tolist(),
                                         itemstyle_opts=opts.ItemStyleOpts(
                                             color="#ec0000",
                                             color0="#00da3c",
                                             border_color="#8A0000",
                                             border_color0="#008F28",
                                         ))
                else:
                    self.mainchart.add_yaxis("kline", [a[0], a[1], a[2], a[3]],
                                         itemstyle_opts=opts.ItemStyleOpts(
                                             color="#ec0000",
                                             color0="#00da3c",
                                             border_color="#8A0000",
                                             border_color0="#008F28",
                                         ))
                # self._vol_chart()
            elif len(a)>5:
                if isinstance(a[0],str):
                    x = self.data[a[0]].apply(lambda x: str(x)[:self.timekey_strn]).tolist()
                    self.x = x
                    self.mainchart.add_xaxis(x)
                    self.mainchart.add_yaxis("kline",
                    self.data.loc[:, [a[1], a[2], a[3], a[4]]].values.tolist(),
                    itemstyle_opts = opts.ItemStyleOpts(
                        color="#ec0000",
                        color0="#00da3c",
                        border_color="#8A0000",
                        border_color0="#008F28",
                    ))
                    self._vol_chart(a[5])
                else:
                    self.mainchart.add_xaxis(a[0])
                    self.mainchart.add_yaxis("kline",[a[1],a[2],a[3],a[4]],
                                         itemstyle_opts=opts.ItemStyleOpts(
                                             color="#ec0000",
                                             color0="#00da3c",
                                             border_color="#8A0000",
                                             border_color0="#008F28",
                                         ))
                    self._vol_chart([a[0],a[5]])
            else:
                return None
        else:
            if self.x:
                self.mainchart.add_xaxis(self.x)
                self.mainchart.add_yaxis("kline", self.data.loc[:, ["open", "close", "low", "high"]].values.tolist(),
                                itemstyle_opts=opts.ItemStyleOpts(
                                    color="#ec0000",
                                    color0="#00da3c",
                                    border_color="#8A0000",
                                    border_color0="#008F28",
                                ))
                self._vol_chart()
    def _vol_chart(self,vol=None):
        chart=Bar()
        x=self.x
        y=None
        if vol:
            if isinstance(vol,str):
                y=self.data[vol].astype("float")
            else:
                x=vol[0]
                y = vol[1]
        else:
            y=self.data["volume"].astype("float")
        chart.add_xaxis(x)
        chart.add_yaxis("vol",y.values.tolist(),label_opts=opts.LabelOpts(is_show=False),bar_width="70%")
        y_ma5=MA(y,5)
        y_ma10 = MA(y, 10)
        line=Line()
        line.add_xaxis(self.x)
        line.add_yaxis("MA5_vol",y_ma5.values.tolist(), is_smooth=True, is_symbol_show=False,tooltip_opts=opts.TooltipOpts(trigger="axis"))
        line.add_yaxis("MA10_vol", y_ma10.values.tolist(), is_smooth=True, is_symbol_show=False,tooltip_opts=opts.TooltipOpts(trigger="axis"))
        self.__set_globle_opt(line)
        chart.overlap(line)
        self.__set_globle_opt(chart)
        self.sub_charts.append(chart)
        self.grad_index = self.grad_index + 1
    def add_oc_order(self,orders):
        data = orders
        if isinstance(data, list):
            for i in data:
                line1 = Line()
                if i["fx"] in ["buy", "b", "B"]:
                    ot = str(i["opentime"])[:self.timekey_strn]
                    ct = str(i["closetime"])[:self.timekey_strn]
                    line1.add_xaxis([ot, ct])
                    if i["closeprice"]>i["openprice"]:
                        line1.add_yaxis("", [i["openprice"], i["closeprice"]], is_symbol_show=False,
                                        linestyle_opts=opts.LineStyleOpts(width=5, color='rgb(255, 0, 0)',type_="dotted"))
                    else:
                        line1.add_yaxis("", [i["openprice"], i["closeprice"]], is_symbol_show=False,linestyle_opts=opts.LineStyleOpts(width=5,color='rgb(255, 0, 0)'))
                elif i["fx"] in ["sell", "s", "S"]:
                    ot = str(i["opentime"])[:self.timekey_strn]
                    ct = str(i["closetime"])[:self.timekey_strn]
                    line1.add_xaxis([ot, ct])
                    if i["closeprice"] < i["openprice"]:
                        line1.add_yaxis("", [i["openprice"], i["closeprice"]], is_symbol_show=False,
                                        linestyle_opts=opts.LineStyleOpts(width=3, color='rgb(0, 255, 0)', type_="dotted"))
                    else:
                        line1.add_yaxis("", [i["openprice"], i["closeprice"]], is_symbol_show=False, linestyle_opts=opts.LineStyleOpts(width=3,color='rgb(0,255,0)'))
                self.mainchart.overlap(line1)
    def check_timkey(self,timekey):
        if self.start:
            if self.end:
                return timekey>=self.start and timekey<=self.end
            else:
                return timekey>=self.start
        else:
            if self.end:
                return timekey<=self.end
            else:
                return True
    def add_bs_signals(self,signals_data):
        data={}
        symbols={"buy":SymbolType.TRIANGLE,"sell":"pin","close":"circle","openbuy":SymbolType.TRIANGLE,
                 "opensell":"pin","closebuy":SymbolType.TRIANGLE,"closesell":"pin"}
        for i in signals_data:
            if self.check_timkey(i["timekey"]):
                key=i["action"]
                if key not in data.keys():
                    data[key]={"x":[],"y":[]}
                data[key]["x"].append(str(i["timekey"])[:self.timekey_strn])
                data[key]["y"].append(i["price"])
        for name,v in data.items():
            if v["x"]:
                es = EffectScatter()
                es.add_xaxis(v["x"])
                if name in symbols.keys():
                    symbol=symbols[name]
                else:
                    if "buy" in name:
                        symbol =SymbolType.TRIANGLE
                    else:
                        symbol ="pin"
                es.add_yaxis(name, v["y"],is_selected=True,
                              symbol=symbol,
                              )
                self.mainchart.overlap(es)
    def add_bs_orders(self,orders):
        data={}
        symbols={"buy":SymbolType.TRIANGLE,"sell":"pin","close":"circle","openbuy":SymbolType.TRIANGLE,
                 "opensell":"pin","closebuy":SymbolType.TRIANGLE,"closesell":"pin"}
        if isinstance(orders,dict):
            for name,v in orders.items():
                buy={"x": [], "y": []}
                sell={"x": [], "y": []}

                for o in v:
                    if o["bs"]=="buy":
                        buy["x"].append(str(o["opentimekey"])[:self.timekey_strn])
                        sell["x"].append(str(o["closetimekey"])[:self.timekey_strn])
                    else:
                        buy["x"].append(str(o["closetimekey"])[:self.timekey_strn])
                        sell["x"].append(str(o["opentimekey"])[:self.timekey_strn])
                    sell["y"].append(o["sellprice"])
                    buy["y"].append(o["buyprice"])
                key0 = "buy_" + name
                key1 = "sell_" + name
                data[key0] = buy
                data[key1] = sell
        else:
            buy = {"x": [], "y": []}
            sell = {"x": [], "y": []}
            for o in orders:
                if o["bs"] == "buy":
                    buy["x"].append(str(o["opentimekey"])[:self.timekey_strn])
                    sell["x"].append(str(o["closetimekey"])[:self.timekey_strn])
                else:
                    buy["x"].append(str(o["closetimekey"])[:self.timekey_strn])
                    sell["x"].append(str(o["opentimekey"])[:self.timekey_strn])
                sell["y"].append(o["sellprice"])
                buy["y"].append(o["buyprice"])
            data["buy"+str(self.orders_n)] = buy
            data["sell"+str(self.orders_n)] = sell
            self.orders_n=self.orders_n+1
        for name,v in data.items():
            if v["x"]:
                es = EffectScatter()
                es.add_xaxis(v["x"])
                if name in symbols.keys():
                    symbol=symbols[name]
                else:
                    if "buy" in name:
                        symbol =SymbolType.TRIANGLE
                    else:
                        symbol ="pin"
                es.add_yaxis(name, v["y"],is_selected=True,
                              symbol=symbol,
                              )
                self.mainchart.overlap(es)
    def add_bs_point(self,orders):
        """

        Args:
            orders:可以是order list；也可以是买卖点数据

        Returns:

        """
        data=orders
        buy_x=[]
        buy_y=[]
        sell_x=[]
        sell_y=[]
        if isinstance(data,dict):
            for i in data.values():
                if self.check_timkey(i["timekey"]):
                    if i.bs == bs.buy:
                        buy_x.append(i.timekey)
                        buy_y.append(i.price)
                    else:
                        sell_x.append(i.timekey)
                        sell_y.append(i.price)
        else:
            if len(data)==4:
                buy_x=data[0]
                buy_y=data[1]
                sell_x=data[2]
                sell_y=data[3]
            else:
                for i in data:
                    if self.check_timkey(i["timekey"]):
                        if i.bs==bs.buy:
                            buy_x.append(i.timekey)
                            buy_y.append(i.price)
                        else:
                            sell_x.append(i.timekey)
                            sell_y.append(i.price)
        es1 = EffectScatter()
        es1.add_xaxis(buy_x)
        es1.add_yaxis("bottom", buy_y,
                      symbol=SymbolType.TRIANGLE,
                      )
        es2 = EffectScatter()
        es2.add_xaxis(sell_x)
        es2.add_yaxis("top", sell_y,
                      symbol="pin",
                      )
        self.mainchart.overlap(es1)
        self.mainchart.overlap(es2)
    def addmain_chart(self,charttype,data):
        """

        Args:
            charttype: line,or bs
                line,x：timekey
            data: list [],可以多个
                bs,data is orders

        Returns:

        """
        if charttype=="line":
            line=Line()
            line.add_xaxis(self.x)
            for i in data:
                line.add_yaxis(i, self.data[i].values.tolist(), is_smooth=False, is_symbol_show=False,is_selected=True,
                                tooltip_opts=opts.TooltipOpts(trigger="axis"))
            self.mainchart.overlap(line)
        elif charttype=="subline":
            line = Line()
            if isinstance(data,list):
                line.add_xaxis(self.x)
                n=0
                for i in data:
                    n=n+1
                    line.add_yaxis("subline"+str(n), self.data[i].values.tolist(), is_smooth=False, is_symbol_show=False,is_selected=True,
                                       linestyle_opts=opts.LineStyleOpts(opacity=0.8,type_="dashed"),
                                       tooltip_opts=opts.TooltipOpts(trigger="axis"))
            elif isinstance(data,str):
                line.add_xaxis(self.x)
                line.add_yaxis("subline", self.data[data].values.tolist(), is_smooth=False, is_symbol_show=False,is_selected=True,
                                       linestyle_opts=opts.LineStyleOpts(opacity=0.8,type_="dashed"),
                                       tooltip_opts=opts.TooltipOpts(trigger="axis"))
            elif isinstance(data,dict):
                for name,v in data.items():
                    line = Line()
                    if isinstance(v,str):
                        line.add_xaxis(self.x)
                        line.add_yaxis(name, self.data[v].values.tolist(), is_smooth=False,
                                       is_symbol_show=False,is_selected=True,
                                       linestyle_opts=opts.LineStyleOpts(opacity=1, type_="dashed"),
                                       tooltip_opts=opts.TooltipOpts(trigger="axis"))
                    elif isinstance(v,dict):
                        x,y=self.get_x_y(v["x"],v["y"])
                        line.add_xaxis(x)
                        line.add_yaxis(name, y, is_smooth=False,
                                       is_symbol_show=False,is_selected=True,
                                       linestyle_opts=opts.LineStyleOpts(opacity=1,type_="dashed"),
                                       tooltip_opts=opts.TooltipOpts(trigger="axis"))
                    self.mainchart.overlap(line)
                return None
            self.mainchart.overlap(line)
        elif charttype=="bs":
            self.add_bs_point(data)
        elif charttype=="openclose":
            #[{"fx":buy/sell,"opentime":timkey,"openprice",closetime,closeprice}]
            self.add_oc_order(data)
        elif charttype=="mark_edot":
            symbles=['circle', 'rect', 'roundRect','diamond', 'arrow']
            data0={}
            if isinstance(data, dict):
                for k,v in data.items():
                    data0[k]={"x":[],"y":[]}
                    if isinstance(v,list):
                        for i in v:
                            if isinstance(i,dict):
                                if self.check_timkey(i["timekey"]):
                                    data0[k]["x"].append(str(i["timekey"])[:self.timekey_strn])
                                    data0[k]["y"].append(i["price"])
                                else:
                                    data0[k]["x"].append(str(i[0])[:self.timekey_strn])
                                    data0[k]["y"].append(i[1])
                    elif isinstance(v,dict):
                        x,y=self.get_x_y(v["x"],v["y"])
                        data0[k]={"x":x,"y":y}
            n=0
            for k,v in data0.items():
                if v["x"]:
                    if "buy" in k or "买" in k:
                        s=symbles[n]
                    elif "sell" in k or "卖" in k:
                        if n==0:
                            n=n+1
                        s=symbles[-n]
                    es1 = EffectScatter()
                    es1.add_xaxis(v["x"])
                    es1.add_yaxis(k, v["y"],is_selected=True,
                                  symbol=s,
                                  )
                    self.mainchart.overlap(es1)
                    if n<5:
                        n=n+1
        elif charttype=="markarea":
            data0=[]
            for i in data:
                data0.append(opts.MarkAreaItem(
                        # name="流量",
                        x=(str(i[0]["timekey"])[:self.timekey_strn],str(i[1]["timekey"])[:self.timekey_strn]),
                        label_opts=opts.LabelOpts(is_show=False),
                        itemstyle_opts=opts.ItemStyleOpts(color="#f1d5cf", opacity=0.1),
                    ))
            self.mainchart.set_series_opts(
                markarea_opts=opts.MarkAreaOpts(
                    is_silent=False,
                    # opacity=0.2,
                    data=data0)
            )
        elif charttype=="markdot":
            data0=[]
            for name,v in data.items():
                for i in v:
                    data0.append(opts.MarkPointItem(name=name, coord=[str(i[0])[:self.timekey_strn], i[1]], value=i[2],symbol=name))
            self.mainchart.set_series_opts(
                markpoint_opts=opts.MarkPointOpts(
                    data=data0)
            )

    def __set_globle_opt(self,chart):
        chart.set_global_opts(
            xaxis_opts=opts.AxisOpts(
                type_="category",
                is_scale=True,
                grid_index=self.grad_index,
                boundary_gap=False,
                axisline_opts=opts.AxisLineOpts(is_on_zero=False),
                axistick_opts=opts.AxisTickOpts(is_show=False),
                splitline_opts=opts.SplitLineOpts(is_show=False),
                axislabel_opts=opts.LabelOpts(is_show=False),
                # split_number=20,
                # min_="dataMin",
                # max_="dataMax",
            ),
            yaxis_opts=opts.AxisOpts(
                grid_index=self.grad_index,
                is_scale=True,
                split_number=2,
                # min_="dataMin",
                # max_="dataMax",
                axislabel_opts=opts.LabelOpts(is_show=True),
                axisline_opts=opts.AxisLineOpts(is_show=True),
                axistick_opts=opts.AxisTickOpts(is_show=True),
                splitline_opts=opts.SplitLineOpts(is_show=True),
            ),
            legend_opts=opts.LegendOpts(is_show=False),
        )
        return chart
    def getx(self,x,tk=19):
        if x:
            if isinstance(x,str):
                return self.data[x].apply(lambda x: str(x)[:tk]).tolist()
            elif isinstance(x,pd.Series):
                return x.apply(lambda x: str(x)[:tk]).tolist()
            elif isinstance(x,dict):
                return list(x.values())
            else:
                return x.tolist()
        else:
            return self.x
    def getdata(self,data):
        d=[]
        if data:
            if isinstance(data,list):
                for i in data:
                    if isinstance(i,str):
                        d.append(self.data[i].values.tolist())
                    elif isinstance(data[0],pd.Series):
                        d.append(i.values.tolist())
                    elif isinstance(data[0],dict):
                        d.append(list(i.values()))
                    else:
                        d.append(i)
            else:
                i=data
                if isinstance(i, str):
                    d.append(self.data[i].values.tolist())
                elif isinstance(data[0], pd.Series):
                    d.append(i.values.tolist())
                elif isinstance(data[0], dict):
                    d.append(list(i.values()))
                else:
                    d.append(i)
        return d
    def add_sub_chart(self,charttype,data,x=None,opts_data={}):
        if x:
            self.x=x
        cname=""
        if charttype=="MACD":
            cname="MACD"
            chart=Bar()
            chart.add_xaxis(self.x)
            chart.add_yaxis(data[2],self.data[data[2]].values.tolist(),yaxis_index=0,label_opts=opts.LabelOpts(is_show=False),bar_width="70%")
            line = Line()
            line.add_xaxis(self.x)
            line.add_yaxis(data[0], self.data[data[0]].values.tolist(),yaxis_index=0, is_smooth=True, is_symbol_show=False,
                            tooltip_opts=opts.TooltipOpts(trigger="axis"))
            line.add_yaxis(data[1], self.data[data[1]].values.tolist(),yaxis_index=0, is_smooth=True, is_symbol_show=False,
                           tooltip_opts=opts.TooltipOpts(trigger="axis"))
            self.__set_globle_opt(line)
            self.__set_globle_opt(chart)
            chart.overlap(line)
        elif charttype=="bar":
            chart = Bar()
            chart.add_xaxis(self.x)
            d = self.getdata(data)
            if isinstance(data[0],str):
                name=data[0]
            else:
                name=opts_data[0].get("name","")
            cname=name
            chart.add_yaxis(name, d[0],yaxis_index=0,label_opts=opts.LabelOpts(is_show=False),bar_width="70%")
            self.__set_globle_opt(chart)
        else:
            chart=Line()
            # xx=self.getx(x)
            chart.add_xaxis(self.x)

            if isinstance(data,list) or isinstance(data,tuple):
                n=0
                for i in data:
                    if opts_data:
                        name = opts_data[n].get("name", "")
                        cname=name
                        yaxis_index0 = opts_data[n].get("yaxis_index", None)
                        n = n + 1
                        if isinstance(i, str):
                            x, y = self.prepare_data(i)
                            chart.add_yaxis(i, y, is_smooth=True, is_symbol_show=False, yaxis_index=yaxis_index0,
                                            tooltip_opts=opts.TooltipOpts(trigger="axis"))
                        elif isinstance(i, list) or isinstance(i,tuple):
                            chart.add_yaxis(series_name=name, y_axis=i, is_smooth=True, is_symbol_show=False,
                                            yaxis_index=yaxis_index0,
                                            tooltip_opts=opts.TooltipOpts(trigger="axis"))
                        else:
                            x, y = self.prepare_data(i)
                            chart.add_yaxis(name, y, is_smooth=True, is_symbol_show=False, yaxis_index=yaxis_index0,
                                            tooltip_opts=opts.TooltipOpts(trigger="axis"))
                    else:
                        name=cname
                        if isinstance(i, str):
                            cname=i
                            x, y = self.prepare_data(field=i)
                            chart.add_yaxis(i, y, is_smooth=True, is_symbol_show=False,
                                            tooltip_opts=opts.TooltipOpts(trigger="axis"))
                        elif isinstance(i, list) or isinstance(i,tuple):
                            chart.add_yaxis(series_name=name, y_axis=i, is_smooth=True, is_symbol_show=False,
                                            tooltip_opts=opts.TooltipOpts(trigger="axis"))
                        else:
                            x, y = self.prepare_data(i)
                            chart.add_yaxis(name, y, is_smooth=True, is_symbol_show=False,
                                            tooltip_opts=opts.TooltipOpts(trigger="axis"))

            elif isinstance(data,dict):
                for k,v in data.items():
                    cname=k
                    x,y=self.prepare_data(v)
                    yaxis_index0 = opts_data.get("yaxis_index0", None)
                    if yaxis_index0:
                        chart.add_yaxis(k, y, is_smooth=True, is_symbol_show=False,yaxis_index=yaxis_index0,
                                    tooltip_opts=opts.TooltipOpts(trigger="axis"))
                    else:
                        chart.add_yaxis(k, y, is_smooth=True, is_symbol_show=False,
                                        tooltip_opts=opts.TooltipOpts(trigger="axis"))

            self.__set_globle_opt(chart)
        self.sub_charts.append(chart)
        # self.sub_charts[cname]=chart

        self.grad_index=self.grad_index+1
    def set_name(self,name):
        self.name=name
    def draw(self,width="1800px",high="l1",show_bars=100):
        if self.isreturn:
            xaxislen = 0
            is_control_axis_index0=True
            pos_right0="3%"
        else:
            is_control_axis_index0=False
            pos_right0 = "1%"
            if self.x:
                if len(self.x)<=show_bars:
                    xaxislen = 0
                else:
                    xaxislen = show_bars * (len(self.x)-show_bars) / len(self.x)
            else:
                xaxislen=0
        x_indexs = list(range(self.grad_index))
        self.mainchart.set_global_opts(title_opts=opts.TitleOpts(title=self.name),
                                       tooltip_opts=opts.TooltipOpts(trigger="axis", axis_pointer_type="cross"),
                                       datazoom_opts=[
                                           opts.DataZoomOpts(range_start=xaxislen, range_end=100, type_='inside',
                                                             xaxis_index=x_indexs,
                                                             orient="both", is_realtime=False),
                                           opts.DataZoomOpts(range_start=xaxislen, range_end=100),
                                           ],
                                       axispointer_opts=opts.AxisPointerOpts(
                                           is_show=True,
                                           link=[{"xAxisIndex": "all"}],
                                           label=opts.LabelOpts(background_color="#777"),
                                       ),
                                       xaxis_opts=opts.AxisOpts(type_="category", boundary_gap=False,
                                                                splitline_opts=opts.SplitLineOpts(is_show=True)),
                                   )
        if high=="l1":
            kline_high = 300
            main_gap_high = 58
            subchart_high = 90
            gap_high = 2
        elif high=="l2":
            kline_high = 400
            main_gap_high = 58
            subchart_high = 135
            gap_high = 2
        else:
            kline_high = 600
            main_gap_high = 70
            subchart_high = 180
            gap_high = 2
        kline_high_delta=0
        if self.isreturn:
            kline_high=842
            kline_high_delta=10
            # main_gap_high = 0
        height0=kline_high+main_gap_high+len(self.sub_charts)*subchart_high+(len(self.sub_charts)+1)*gap_high
        self.width=width
        self.height=str(height0)+"px"
        grid_chart = Grid(
            init_opts=opts.InitOpts(
                # js_host=js_host,
                width=self.width,
                height=self.height,
                page_title=self.name,
                animation_opts=opts.AnimationOpts(animation=False),
                bg_color="#ffffff"
            ),
        )
        #h0=600/height0
        grid_chart.add(
            self.mainchart,is_control_axis_index=is_control_axis_index0,
            grid_opts=opts.GridOpts(pos_left="3%", pos_right=pos_right0, height=str(kline_high-kline_high_delta)+"px"),
        )
        h0=kline_high+main_gap_high
        for chart in self.sub_charts:
            ss = chart.options["series"]
            if len(ss) > 0:
                cname = ss[0]["name"]
            if self.is_sub_show:
                chart.set_global_opts(title_opts=opts.TitleOpts(title=cname, pos_top=str(h0)+"px"),legend_opts=opts.LegendOpts(is_show=True,pos_top=str(h0)+"px"))
            else:
                chart.set_global_opts(title_opts=opts.TitleOpts(title=cname, pos_top=str(h0)+"px"),legend_opts=opts.LegendOpts(is_show=False,pos_top=str(h0)+"px"))

            grid_chart.add(
                chart,is_control_axis_index=is_control_axis_index0,
                grid_opts=opts.GridOpts(pos_left="3%", pos_right=pos_right0,pos_top=str(h0)+"px", height=str(subchart_high)+"px"),
            )
            h0=h0+subchart_high+gap_high
        return grid_chart

def ilter_split_plot_data(bars,timekey_set):
    barsd=pd.DataFrame(bars)
    barsd.sort_values("timekey",inplace=True)
    barsd.drop_duplicates("timekey",inplace=True)
    barsd.index=range(len(barsd))
    if isinstance(timekey_set,dict):
        for name,v in timekey_set.items():
            if isinstance(v,list):
                index0 = barsd.loc[barsd["timekey"] == v[0]].index.tolist()[0]
                index1 = barsd.loc[barsd["timekey"] == v[1]].index.tolist()[0]
                n1 = index0 - 190
                n2 = index1 + 10
                if n1 < 0:
                    n1 = 0
            else:
                index0=barsd.loc[barsd["timekey"]==v].index.tolist()[0]
                n1=index0-190
                n2=index0+10
                if n1<0:
                    n1=0
            d=barsd.iloc[n1:n2,]
            vv=d["timekey"].tolist()
            yield (name,d,vv[0],vv[-1])
    else:
        for i in timekey_set:
            name=i[0]
            index0 = barsd.loc[barsd["timekey"] == i[1]].index.tolist()[0]
            index1 = barsd.loc[barsd["timekey"] == i[2]].index.tolist()[0]
            n1 = index0 - 190
            n2 = index1 + 10
            if n1 < 0:
                n1 = 0
            d = barsd.iloc[n1:n2, ]
            vv = d["timekey"].tolist()
            yield (name, d, vv[0], vv[-1])
def plot_echarts(bars=None,main_fig={},sub_fig={},timekey_strn=19,fig_width="1650px",fig_high_level="l3",timekey_set={},html_url=None,show_bars=100):
    """
    Args:
        bars: [],根据main_fig，sub_fig定义拼凑数据
        main_fig:定义主图的内容：type:参数指定
        sub_fig: 定义副图的内容：type:参数指定
        类型只支持k线，曲线，bar，涟漪点，三种，kline,line,
    Returns:
        多个图对象，主要是看 数据太多就分多个图 1万
    """
    # if bars is None:
    #     return None
    if timekey_set:
        t1=None
        for vv in ilter_split_plot_data(bars,timekey_set):
            chart0 = chart(data=vv[1], timekey_strn=timekey_strn,start=vv[2],end=vv[3])
            for k, v in main_fig.items():
                if k == "kline":
                    if v:
                        chart0.mainchart_kline(v)
                elif k == "fenshi":
                    if v:
                        chart0.mainchart_fenshitu(v)
                elif k == "bs_signals":
                    if v:
                        chart0.add_bs_signals(v)
                elif k=="net":
                    isfirst=True
                    for kk,vv in v.items():
                        if isfirst:
                            isfirst=False
                        chart0.add_net(bars,kk,vv)
                else:
                    if v:
                        chart0.addmain_chart(k, v)
            if isinstance(sub_fig,list):
                for v in sub_fig:
                    chart0.add_sub_chart(v[0], v[1])
            else:
                for k, v in sub_fig.items():
                    chart0.add_sub_chart(k, v)
            chart1 = chart0.draw(fig_width, fig_high_level,show_bars)
            if t1 is None:
                # heigh=int(chart0.height.replace("px",""))+10
                # heigh=str(heigh) + ".px"
                t1=Timeline(init_opts=opts.InitOpts(
                    js_host=js_host,
                    width=chart0.width,
                    height=chart0.height))
            t1.add(chart1,vv[0])
        if html_url:
            dp = os.path.dirname(html_url)
            if not os.path.exists(dp):
                os.mkdir(dp)
            t1.render(html_url)
        return t1
    else:
        chart0=chart(data=bars,timekey_strn=timekey_strn)
        for k,v in main_fig.items():
            if k=="kline":
                if v:
                    chart0.mainchart_kline(v)
            elif k=="fenshi":
                if v:
                    chart0.mainchart_fenshitu(v)
            elif k=="bs_signals":
                if v:
                    chart0.add_bs_signals(v)
            elif k == "net":
                isfirst = True
                for kk, vv in v.items():
                    if isfirst:
                        chart0.mainchart_net(bars, kk, vv)
                        isfirst = False
                    else:
                        chart0.add_net(bars, kk, vv)
            else:
                if v:
                    chart0.addmain_chart(k, v)
        if isinstance(sub_fig, list):
            for v in sub_fig:
                chart0.add_sub_chart(v[0], v[1])
        else:
            for k, v in sub_fig.items():
                chart0.add_sub_chart(k,v)
        chart0 = chart0.draw(fig_width,fig_high_level,show_bars)
        if html_url:
            dp=os.path.dirname(html_url)
            if not os.path.exists(dp):
                os.mkdir(dp)
            chart0.render(html_url)
        return chart0